<?php
/**
 * Data model for statistics
 * @package contenite
 */

/**
 * @package contenite
 * Database wrapper.
 */
class DB {
  var $db;
  var $db_slave;
  
function __construct() {
  global $config;

  $this->db = mysql_connect($config['db_master']['server'], $config['db_master']['username'], $config['db_master']['password'], TRUE);
  if (!$this->db) {
    die(mysql_error());
  }
  mysql_select_db($config['db_master']['name'], $this->db);
  $this->query('set names utf8');

  if (isset($config['db_slave'])) {
    $this->db_slave = mysql_connect($config['db_slave']['server'], $config['db_slave']['username'], $config['db_slave']['password'], TRUE);
    if (!$this->db_slave) {
      die(mysql_error());
    }
    mysql_select_db($config['db_slave']['name'], $this->db_slave);
    $this->query('S:set names utf8');
  }
  else {
    $this->db_slave =& $this->db;
  }
}

/**
 * Query the database.
 *
 * The first parameter is the SQL query. If this is prefixed with 'S:',
 * the query goes to the slave database.
 */
function query() {
  $raw_args = func_get_args();
  $q = array_shift($raw_args);

  return $this->vquery($q, $raw_args);
}

function vquery($q, $raw_args) {
  global $DEBUG;

  if (strpos($q, 'S:') === 0) {
    $q = substr($q, 2);
    $db = $this->db_slave;
  }
  else {
    $db = $this->db;
  }

  $matches = array();
  $args = array();
  preg_match_all('/%[ds]/', $q, $matches, PREG_PATTERN_ORDER);
  foreach ($matches[0] as $match) {
    $raw_arg = array_shift($raw_args);
    if (is_array($raw_arg)) {
      $a = array();
      foreach ($raw_arg as $v) {
        $a[] = $match == '%s' ? ('\'' . addslashes($v) . '\'') : $v;
      }
      $args[] = '(' . join(',', $a) . ')';
    }
    else {
      $args[] = $match == '%s' 
        ? ('\'' . addslashes($raw_arg) . '\'') 
        : $raw_arg;
    }
  }
  // voodoo stuff to allow % in query
  // $q = preg_replace('/\@(\w)/', '%$1', vsprintf($q, $args));

  $q = vsprintf($q, $args);
  if ($DEBUG > 1) error_log(vsprintf($q, $args));
  return $this->check(mysql_query($q, $db), $q, $db);
}

function check($rs, $q, $db = NULL) {
  global $DEBUG;
  
  $q = trim($q);
  if (!$db) {
    if (strpos($q, 'S:') === 0) {
      $db = $this->db_slave;
      $q = substr($q, 2);
    }
    else {
      $db = $this->db;
    }
  }
  if (!$rs) {
    error_log("ERROR in {{$q}}: " . mysql_error($db));
    return FALSE;
  }
  if ($DEBUG > 1) error_log("RESULT of {{$q}}: " . ($rs === TRUE 
    ? (stripos($q, 'insert') === 0 || stripos($q, 'replace') === 0 
      ? mysql_insert_id($db) : mysql_affected_rows($db))
    : mysql_num_rows($rs)));
  return $rs === TRUE 
    ? (stripos($q, 'insert') === 0 || stripos($q, 'replace') === 0 
      ? mysql_insert_id($db) : mysql_affected_rows($db))
    : $rs;
}

function num_rows($rs) {
  return mysql_num_rows($rs);
}

function affected_rows($q) {
  if (strpos($q, 'S:') === 0) {
    $db = $this->db_slave;
  }
  else {
    $db = $this->db;
  }
  return mysql_affected_rows($db);
}

function fetch($rs) {
  if (!$rs) {
    error_log(bt());
    return NULL;
  }
  else {
    return mysql_fetch_assoc($rs);
  }
}

function create_table($name, $q) {
  global $config;
  
  $this->query('drop table if exists ' . $name);
  $this->query('create table ' . $name . ' ( ' . $q . ' ) ENGINE=MyISAM DEFAULT CHARSET=utf8');
  $this->query('alter table ' . $name 
    . ' comment = \'schema_version=' . $config['db_master']['version'] . '\''); 
}

function alter_table($name, $q) {
  global $config;
  
  $this->query('alter table ' . $name . ' ' . $q); 
  $this->query('alter table ' . $name 
    . ' comment = \'schema_version=' . $config['db_master']['version'] . '\''); 
}

} // class DB

$DB = new DB;
